(load "mm.lisp")
(load "mm-solver.lisp")
(load "mmnetwork.lisp")
(load "mm-algorithms.lisp")

;;note* to run the mm package
;;you have to type '(in-package :mm-soh)' in clisp
;;to exit: type '(cl:in-package :cl-user)' in clisp

;;=======================================================================
;; GLOBAL VARIABLES

(defvar *mm-test-player*)

(setf *mm-test-player*
  (make-instance 'mm::player
    :name 'mm-test
	:guess-fn 'mm-test
  )
)


;;=======================================================================
;; MAIN FUNCTIONS

;;taken from mm-solver, only thing added is an initialization of guessNode
(defun mm-test (&optional (colors *colors*) (code-length *code-length*)
			     (generator #'mm-gen-random)
			     &aux reds whites)
  "Stupid generate-and-test guesser that doesn't pay any attention to the whites & reds"
  
  (declare (ignore generator))
  
  (setf *guesses-made* nil)
  (setf *alrdy-gen* nil) 
  (setf *eligible-guesses* nil) 
  (setf guess (uniqueRandGuess code-length colors) )
  ;(setf *max-pop* (expt code-length (list-length colors) ))
  (setf *max-pop* (expt (list-length colors) code-length ))
  
  (loop while guess
    do
      (progn
        (format t "Guessing ~A...~%" guess)
	    
	    (multiple-value-setq (reds whites) (mm-score guess *code* colors))
	    ;(FORMAT t "reds: ~A whites: ~A~%" reds whites)
	    
	    (setq newGuessNode (make-guessNode :guess guess :fitness 0) )
	    
	    ;;some code to compute fitness
	    (calculateFitness newGuessNode reds whites)
	    
	    (setq *guesses-made* (APPEND-TO-LIST newGuessNode  *guesses-made*) )
	    (setq *alrdy-gen* (APPEND-LIST-TO-LIST guess  *alrdy-gen*) )
	    
	    (cond
	      ( (eq reds code-length)
		    (format t "mm-test guessed ~s correctly in ~A guesses!~%" guess (list-length *guesses-made*))
		    (setf *alrdy-gen* nil)
		    (setf *guesses-made* nil)
		    (setf *eligible-guesses* nil) 
		    (return-from mm-test)
		  )
		  (t
		    (setf guess (radu-rosu code-length colors))
		    ;(setf guess (trio code-length colors))
		  )
		)
      )
  )
)


;;taken from network code
;;IP is a string and port is an int
(defun mmPlayer (ip port)
  (setq i 0)
  (let* ((server (openConnection ip port)))
    ;read the problem description from the server
    (multiple-value-bind (numPegs colorList) (receiveDescription server)
    
      ;send an initial guess
      (progn
        (setf *alrdy-gen* nil)
        (setq guess (uniqueRandGuess numPegs colorList) )
        (sendGuess server (listToString guess) )
      )

      ;get a result from the server
      ;this should be nil on the first call
      
      (loop while guess
        do
          (multiple-value-bind (reds whites) (receiveResult server)
            (progn
              (format t "~A ~A~%" reds whites)
              (if (EQ reds numPegs)
                (setf guess nil)
            
                (progn
                  (setq newGuessNode (make-guessNode :guess guess :numRed reds :numWhite whites :fitness 0))
                  (format t "~A~%" newGuessNode)
              
                  ;generate fitness code. needs to be added
                  (setq *guesses-made* (APPEND-TO-LIST newGuessNode  *guesses-made*) )
                  (setq *alrdy-gen* (APPEND-LIST-TO-LIST guess  *alrdy-gen*) )
               
                  ;(setf guess (uniqueRandGuess numPegs colorList))
                  (setf guess (radu-rosu numPegs colorList))
                  (sendGuess server (listToString guess) )
                )
              )
          )
        ) ;end do
      ) ;end loop
    ) ;end multiple-value-bind
  ) ;end let
  
  (FORMAT -t "Program ended, ~A tries~%" i)
)